package com.ponhu.ea2.stockcenter.controller;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.ponhu.ea2.common.basic.model.PagedResult;
import com.ponhu.ea2.stockcenter.dto.GWallWarehouseDto;
import com.ponhu.ea2.stockcenter.dto.OrderInfoDTO;
import com.ponhu.ea2.stockcenter.dto.StockQueryListDTO;
import com.ponhu.ea2.stockcenter.enums.DefinedSystem;
import com.ponhu.ea2.stockcenter.query.ApplyFreeQuery;
import com.ponhu.ea2.stockcenter.service.bms.StockCommonService;
import com.ponhu.ea2.stockcenter.service.bms.StockForOMSService;
import com.ponhu.ea2.stockcenter.service.bms.StockForPurchaseCenterService;
import com.ponhu.ea2.stockcenter.service.bms.StockForWMSService;
import com.ponhu.ea2.stockcenter.vo.*;
import com.ponhu.ea2.wmscenter.model.bms.dto.PhWarehouseDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/stock")
@Api(tags = "库存接口", value = "StockController")
public class StockController {

    @DubboReference(version = "1.0.0", check = false)
    private StockCommonService stockCommonService;

    @DubboReference(version = "1.0.0", check = false)
    private StockForOMSService stockForOMSService;

    @DubboReference(version = "1.0.0", check = false)
    private StockForPurchaseCenterService stockForPurchaseCenterService;

    @DubboReference(version = "1.0.0", check = false, timeout = 3600000)
    private StockForWMSService stockForWMSService;

    /**
     * 查询指定货品的仓库位置和库存数量
     *
     * @return
     */
    @ApiOperation(value = "查询指定货品的仓库位置和库存数量")
    @GetMapping("/getReallyStockInfo")
    public ReturnResponseBean<List<InventoryStockWhVO>> getReallyStockInfo(
            @RequestParam Collection<String> inventoryCodeList) {
        if (CollectionUtils.isEmpty(inventoryCodeList))
            return ReturnResponseBean.error("货品编码集合不可为空");

        return stockCommonService.getReallyStockInfo(inventoryCodeList);
    }

    /**
     * 获取全部仓库信息列表
     *
     * @return
     */
    @ApiOperation(value = "获取全部仓库信息列表")
    @GetMapping("/getAllWarehouseInfos")
    public ReturnResponseBean<List<WarehouseInfoVo>> getAllWarehouseInfos() {

        return ReturnResponseBean.ok(stockCommonService.getAllWarehouseInfos());
    }

    /**
     * 条件查询全部货品实时库存列表
     *
     * @return
     */
    @ApiOperation(value = "条件查询全部货品实时库存列表")
    @PostMapping("/getAllInventoryStocks")
    public ReturnResponseBean<PagedResult<StockQueryListVO>> getAllInventoryStocks(
            @RequestBody StockQueryListDTO stockQueryListDTO) {

        int pageIndex = stockQueryListDTO.getPageIndex();
        int pageSize = stockQueryListDTO.getPageSize();
        if (pageIndex < 1 || pageSize < 1) {
            return ReturnResponseBean.error("分页参数错误");
        }

        return ReturnResponseBean.ok(stockCommonService.getAllInventoryStocks(stockQueryListDTO));
    }

    @ApiOperation(value = "根据货品编码分页查询调拨在途明细数据")
    @PostMapping("/getApplyFreeStockDetail")
    public ReturnResponseBean<PagedResult<ApplyFreeStockVO>> getApplyFreeStockDetail(
            @RequestBody ApplyFreeQuery query) {

        int pageIndex = query.getPageIndex();
        int pageSize = query.getPageSize();
        if (pageIndex < 1 || pageSize < 1) {
            return ReturnResponseBean.error("分页参数错误");
        }

        return stockCommonService.getApplyFreeStockDetail(query);
    }

    /**
     * 查询指定货品编码的销售库存占用
     *
     * @return
     */
    @ApiOperation(value = "查询指定货品编码的销售库存占用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "inventoryCode", value = "货品编码",
                    dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageIndex", value = "分页页码",
                    dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页大小",
                    dataType = "int", paramType = "query", required = true)
    })
    @GetMapping("/getSaleOccupyVosByCode")
    public ReturnResponseBean<PagedResult<StockSaleOccupyVO>> getSaleOccupyVosByCode(
            @RequestParam(value = "inventoryCode") String inventoryCode,
            @RequestParam(value = "pageIndex") Integer pageIndex,
            @RequestParam(value = "pageSize") Integer pageSize) {

        if (pageIndex < 1 || pageSize < 1) {
            return ReturnResponseBean.error("分页参数错误");
        }

        return ReturnResponseBean.ok(stockCommonService.getSaleOccupyVosByCode(inventoryCode, pageIndex, pageSize));
    }

    /**
     * 查询指定货品编码的实物库存占用
     *
     * @return
     */
    @ApiOperation(value = "查询指定货品编码的实物库存占用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "inventoryCode", value = "货品编码",
                    dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageIndex", value = "分页页码",
                    dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "分页大小",
                    dataType = "int", paramType = "query", required = true)
    })
    @GetMapping("/getWhOccupyVosByCode")
    public ReturnResponseBean<PagedResult<StockWhOccupyVO>> getWhOccupyVosByCode(
            @RequestParam(value = "inventoryCode") String inventoryCode,
            @RequestParam(value = "pageIndex") Integer pageIndex,
            @RequestParam(value = "pageSize") Integer pageSize) {

        if (pageIndex < 1 || pageSize < 1) {
            return ReturnResponseBean.error("分页参数错误");
        }

        return ReturnResponseBean.ok(stockCommonService.getWhOccupyVosByCode(inventoryCode, pageIndex, pageSize));
    }

    @ApiOperation(value = "测试初始化接口")
    @RequestMapping(value = "/init", method = RequestMethod.GET)
    public ReturnResponseBean<Boolean> initData(@RequestParam @NotEmpty String secret) {
        if ("chushihuayidingchenggong".equals(secret)) {
            stockCommonService.initStockData();
        }
        return ReturnResponseBean.ok(true);
    }

    @ApiOperation(value = "测试取消销售订单/取消采退申请单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "docNo", value = "订单号",
                    dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "definedSystem", value = "对接系统",
                    dataType = "enum", paramType = "query", required = true)
    })
    @RequestMapping(value = "/cancelOrderOccupy", method = RequestMethod.GET)
    public ReturnResponseBean cancelOrderOccupy(@RequestParam @NotEmpty String docNo, @RequestParam DefinedSystem definedSystem) {
        ReturnResponseBean<String> token = stockCommonService.getStockRequestToken(definedSystem);
        if (DefinedSystem.OMS.equals(definedSystem)) {
            return stockForOMSService.cancelSalesOrderOccupyStock(token.getData(), docNo);
        } else {
            return stockForPurchaseCenterService.cancelPurchaseReturnApplyOccupyStock(token.getData(), docNo);
        }
    }

    @ApiOperation(value = "测试销售订单占用/采退申请单占用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "definedSystem", value = "对接系统",
                    dataType = "enum", paramType = "query", required = true)
    })
    @RequestMapping(value = "/makeOrderOccupyStock", method = RequestMethod.POST)
    public ReturnResponseBean makeOrderOccupyStock(@RequestBody OrderInfoDTO orderInfoDTO, @RequestParam DefinedSystem definedSystem) {
        ReturnResponseBean<String> token = stockCommonService.getStockRequestToken(DefinedSystem.OMS);
        if (DefinedSystem.OMS.equals(definedSystem)) {
            return stockForOMSService.salesOrderOccupyStock(token.getData(), orderInfoDTO);
        } else {
            return stockForPurchaseCenterService.purchaseReturnApplyOccupyStock(token.getData(), orderInfoDTO);
        }
    }

    @ApiOperation(value = "测试测试获取token接口")
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ReturnResponseBean<String> test() {
        ReturnResponseBean<String> requestToken = stockCommonService.getStockRequestToken(DefinedSystem.OMS);
        log.info("测试获取token成功");
        return requestToken;
    }

    @PostMapping(value = "/batchSalesOrderOccupyStock")
    @ApiOperation(value = "测试批量销售占用库存")
    public ReturnResponseBean batchSalesOrderOccupyStock(@Validated
                                                         @RequestBody List<OrderInfoDTO> orderInfoDTOList) {

        List<BatchOccupyResultVO> collect = orderInfoDTOList.stream().map(orderInfoDTO -> {
            String stockRequestToken = stockCommonService
                    .getStockRequestToken(DefinedSystem.WMS).getData();
            ReturnResponseBean<OrderOccupyInfoVO> result = stockForOMSService.salesOrderOccupyStock(stockRequestToken, orderInfoDTO);
            if (result.getCode() != 200) {
                return new BatchOccupyResultVO().setOrderNo(orderInfoDTO.getDocNo()).setCode(result.getCode()).setMsg(result.getMsg());
            } else {
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());

        return ReturnResponseBean.ok(collect);

    }

    @PostMapping(value = "/batchCancelSalesOrderOccupyStock")
    @ApiOperation(value = "测试批量取消销售占用库存")
    public ReturnResponseBean batchCancelSalesOrderOccupyStock(@NotEmpty(message = "订单号不能为空")
                                                               @RequestBody List<String> orderNoList) {

        List<BatchOccupyResultVO> collect = orderNoList.stream().map(orderNo -> {
            String stockRequestToken = stockCommonService
                    .getStockRequestToken(DefinedSystem.WMS).getData();

            ReturnResponseBean<OrderOccupyInfoVO> result = stockForOMSService.cancelSalesOrderOccupyStock(stockRequestToken, orderNo);

            if (result.getCode() != 200) {
                return new BatchOccupyResultVO().setOrderNo(orderNo).setCode(result.getCode()).setMsg(result.getMsg());
            } else {
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());

        return ReturnResponseBean.ok(collect);

    }

    @ApiOperation(value = "测试同步仓库信息接口")
    @PostMapping(value = "/syncWarehouseInfo")
    public ReturnResponseBean<Boolean> syncWarehouseInfo(@RequestBody List<GWallWarehouseDto> warehouseDtoList) {
        ReturnResponseBean<Boolean> result = stockForWMSService.saveOrUpdateWarehouseInfo(warehouseDtoList, "BMS-API");
        log.info("测试同步仓库信息接口成功");
        return result;
    }

}
